/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package BaseDatos;

import static Auxiliares.MensajesCodigosError.*;
import Controladores.GestorMensajes;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 *
 * @author Marko
 */
public class GestorConexionBD {

////////////////////////////////////////////////////////////////////////////////
// Constructores
////////////////////////////////////////////////////////////////////////////////

    /**
     * constructor por defecto de la clase
     */
    private GestorConexionBD() {
        conexionMySQL = null;
        adminSentenciasMySQL = null;
        /*BD = "/sapecbd";
        DRIVERS = "com.mysql.jdbc.Driver";
        CONTRASENA = "evgA93zx";
        URL = "jdbc:mysql://148.209.65.85:3306";
        USUARIO = "administrador";*/
        
        BD = "/sapecbd";
        DRIVERS = "com.mysql.jdbc.Driver";
        CONTRASENA = "";
        URL = "jdbc:mysql://localhost:3306";
        USUARIO = "root";
    }

////////////////////////////////////////////////////////////////////////////////
// Interfaz de la clase
////////////////////////////////////////////////////////////////////////////////

    /**
     * asegura que solo se cree un administrador de la conexion a la base de datos
     * @return Devuelve la unica instancia de la clase
     */
    public synchronized static GestorConexionBD obtenerPermisosAdministradorConexion() {
        if(administradorConexion == null){
            return crearNuevaInstancia();
        }
        return administradorConexion;
    }
    
    /**
     * Administra la apertura de la conexion con al base de datos
     * @return conexion ya establecida con la base de datos
     */
    public Statement abrirConexionBD(){
        cargarDriversConexionBD();
        establecerConexionServidorBD();
        establecerConexionBD();
        return crearAdministradorSentenciasMySQL();
    }
    
    /**
     * Adminsitra el cerrado de la conexion con la base de datos 
     */
    public void cerrarConexionBD(){
        try{
            adminSentenciasMySQL.close();
            conexionMySQL.close();
            administradorConexion = null;
        }catch(SQLException log){
            GestorMensajes administradorMensajes = new GestorMensajes();
            administradorMensajes.mensajeError(log, "cerrando la conexion");
        }
    }

    /**
     * Comprueba que la base de datos y las tablas existan
     */
    public void comprobarConexionBaseDatosYTablas(){
        abrirConexionBD();
        comprobarConexionTablas();
        cerrarConexionBD();
    }
    
////////////////////////////////////////////////////////////////////////////////
// Metodos Privados
////////////////////////////////////////////////////////////////////////////////
    
    /**
     * se encarga de que solo se cree un administrador de las conexiones a la base de datos
     * @return administrador de la conexion
     */
    private static GestorConexionBD crearNuevaInstancia(){
        administradorConexion = new GestorConexionBD();
        return administradorConexion;
    }

    /**
     * Carga los drivers necesarios para la conexion con la base de datos
     */
    private void cargarDriversConexionBD(){
        try {
            Class.forName(DRIVERS);
        } catch (ClassNotFoundException log) {
            GestorMensajes administradorMensajes = new GestorMensajes();
            administradorMensajes.mensajeError(log.getMessage());
        }
    }    
    
    /**
     * Establece una conexion con el servidor
     * no este creada
     */
    private void establecerConexionServidorBD(){
        try {
            conexionMySQL = (Connection) DriverManager.getConnection(URL, USUARIO, CONTRASENA);
        } catch (SQLException log) {
            System.out.println(log.getMessage());
            GestorMensajes administradorMensajes = new GestorMensajes();
            administradorMensajes.mensajeError(log, "Estableciendo la conexion");
        }
    }
    
    /**
     * Establece la conexion con la base de datos
     */
    private void establecerConexionBD(){
        try{
            conexionMySQL = (Connection) DriverManager.getConnection(URL.concat(BD),
                     USUARIO,CONTRASENA);
        } catch (SQLException log) {
            if(log.getErrorCode() == BASE_DATOS_NO_ENCONTRADA){
                GestorMensajes administradorMensajes = new GestorMensajes();
                administradorMensajes.mensajeError(log, "sapec");
                adminSentenciasMySQL = crearAdministradorSentenciasMySQL();
                GestorBaseDatos administradorBD = GestorBaseDatos.obtenerPermisosAdministradorBD();    
                administradorBD.crearBaseDatosSAPEC(adminSentenciasMySQL);
            
            }else{
                GestorMensajes administradorMensajes = new GestorMensajes();
                administradorMensajes.mensajeError(log, "Al establecer conexion con la base de datos");
            }
        }
    }
    
    /**
     * @return Devuelve la conexion con la base de datos o nulo en caso de que 
     * ocurra una excepcion 
     */
    private Statement crearAdministradorSentenciasMySQL(){
        try {
            adminSentenciasMySQL = (Statement) conexionMySQL.createStatement();
            return adminSentenciasMySQL;
        } catch (SQLException log) {
            GestorMensajes administradorMensajes = new GestorMensajes();
            administradorMensajes.mensajeError(log, "Al intentar crear la sentencia");
            return null;
        }
    }
    
    /**
     * Comprueba la conexion con las tablas de la base de datos
     */
    private void comprobarConexionTablas(){
        GestorBaseDatos administradorBaseDatos = GestorBaseDatos.obtenerPermisosAdministradorBD();
        administradorBaseDatos.verificarTablas(adminSentenciasMySQL);
    }
    
////////////////////////////////////////////////////////////////////////////////
// Declaracion de Variables
////////////////////////////////////////////////////////////////////////////////
    
    private Statement adminSentenciasMySQL;
    private static GestorConexionBD administradorConexion = null;
    private Connection conexionMySQL;
    
    private final String BD;
    private final String CONTRASENA;
    private final String DRIVERS;
    private final String URL;
    private final String USUARIO;
}